﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;

namespace User.Web.Common.WebAttributes
{
    /// <summary>
    /// Hilfsattribute zum automatisierten erstellen von KnockoutJs Attributen an unseren Controls
    /// </summary>
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public class KockoutJsAttributesAttribute : Attribute, IMetadataAware
    {
        /// <summary>
        /// String der den Key für die "HtmlTagKnockoutValuesKey" Collection enthält in der unsere Attributliste liegt.
        /// </summary>
        public const string HtmlTagKnockoutValuesKey = "HtmlTagKnockoutValues";

        /// <summary>
        /// Wird beim Erstellen der Metadaten für Unser Model aufgerufen und setzt in der passenden Collection
        /// unsere AttributCollection auf die wir dann in den Templates zugreifen können.
        ///  </summary>
        /// <param name="metadata"></param>
        public void OnMetadataCreated(ModelMetadata metadata)
        {
            //metadata.TemplateHint = "Strings";
            metadata.AdditionalValues[HtmlTagKnockoutValuesKey] = OptionalAttributes();
        }

        /// <summary>
        /// Gibt an ob zusätzlich noch der ValueUpdate für KeyDown eingebunden werden soll
        /// </summary>
        public bool AddValueUpdateAfterKeyDown { get; set; }

        /// <summary>
        /// Der Name des Attributes z.B. data-bind
        /// </summary>
        public string AttributeName { get; set; }

        /// <summary>
        /// Das Property auf das gebunden werden soll, z.B. value, text
        /// </summary>
        public string PropertyBindName { get; set; }

        /// <summary>
        /// Die KnockoutVariable auf die gebunden werden soll, d.h. der name aus dem Model.
        /// input data-bind="value: someValue, valueUpdate: 'afterkeydown'"   --> here: someValue
        /// </summary>
        public string KnockoutVariableName { get; set; }

        /// <summary>
        /// Erstellt aus den jeweils gesetzten Attributen eine Liste aus Attributname und Value.
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, object> OptionalAttributes()
        {
            var options = new Dictionary<string, object>();

            //Das Anlegen des Knockout Attributes ist nur möglich, wenn alle Properties gesetzt wurden.
            if (!string.IsNullOrEmpty(AttributeName) && !string.IsNullOrEmpty(PropertyBindName) && !string.IsNullOrEmpty(KnockoutVariableName))
            {
                //Je nach Typ evtl. zusätzliche Parameter unterbringen
                string additionalParams = string.Empty;
                //Nur wenn der Update auch eingebunden werden soll, diesen verwenden
                if (AddValueUpdateAfterKeyDown)
                {
                    //Beim Typ value, zusätzlich valueUpdate mit einbinden, damit das Model auf aktualisiert wird.
                    additionalParams = ", valueUpdate: 'afterkeydown'";
                }

                options.Add(AttributeName,string.Format("{0}: {1} {2}", PropertyBindName, KnockoutVariableName, additionalParams));
            }

            return options;
        }
    }
}